AFNetworking毫无疑问是目前iOS开发中(Objective-C)最好的第三方网络库。一般规模的app使用AFNetworking就可以完成所有需求,不需要自己造轮子。
在使用AFNetworking的过程中遇到了许多坑,也获得了不少经验,在这里总结一下,希望能够帮助到大家。
##AFNetworking进一步封装
AFNetworking 3.x 已经为我们提供了丰富而且易用的API,但还是不够。AFNetworking是一个通用的库,而在我们自己的项目中,有特定的需求,而且往往在许多类中都需要用到网络请求。对AFNetworking进一步封装,能够大大简化代码,减少重复。
举个例子,新建一个CDMNetworkManager类,继承AFHTTPSessionManager。
|
|
|
|
初始化方法中使用了单例模式,这样与服务器的连接不会断掉,省去了每次建立连接时三次握手等过程。如果有多个URL地址,可以创建多个单例。如果有更多特殊的要求,比如设置超时时间等,可以在这个方法中设置。
具体的网络请求方法这里只封装了一个简单的post方法,如果有需要可以封装别的方法。
调用的时候很简单,在任何一个需要发送post请求的类中:
调试工具
曾经我每次网络请求调试的时候只会在回调里写log,然后在控制台里一行一行的仔细查找。如果这个请求返回的内容很多,在Xcode里的显示效果就很差,而且不能直接显示中文。体验很差!
这时候需要神器Charles
上面是Charles的截图,能够监听Mac的所有网络请求并且显示各种格式的内容,非常好用。如果用模拟器的话就可以直接用Charles抓包,如果真机调试的话,需要设置一下iPhone,网上也有很多教程。
虽然是付费软件,但是不买license只是打开时会有10秒延时,每隔30分钟自动关闭。
##常见错误
Error Domain=com.alamofire.error.serialization.response Code=-1016 “Request failed: unacceptable content-type: text/html”
出现这个问题的原因有很多,从表面上看是返回数据的格式不支持text/html,但是为什么返回了text/html?原因不唯一。
首先要看请求的response code,如果是200,说明请求已经传到服务器并且成功返回,返回的格式是text/html。AFNetworking的默认response serializer是AFJSONResponseSerializer,不支持text/html。
这时需要在manager的初始化方法中增加一下代码。或者与服务器开发人员沟通,改写服务器端。
如果response code是400,说明服务器根本没有收到请求。这时为什么返回了一个text/html的数据呢?返回的数据在Xcode控制台上显示为16进制,但是在Charles里我们可以看到结果
这是自动返回的一个错误页面,而不是服务器返回的数据格式不对。这时候再去找response serializer的问题就南辕北辙了。
那么为什么服务器没有受到请求?
一种可能是baseURL的问题。AFHTTPSessionManager的初始化中用到了baseURL,与之后的path拼接时可能出错,检查一下。
还有可能是request serializer的问题。AFNetworking默认的是AFHTTPRequestSerializer。如果服务器接受的参数只能是json的话,需要使用AFJSONRequestSerializer。
可能还有其他各种各样奇怪的原因,欢迎大家补充。
作者时间、能力有限,文章难免有不足之处,请大家指正。